﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

public class Weapon: Item
{
    public enum DamageType
    {
        TYPE_ENERGY,
        TYPE_KINETIC,
        TYPE_EXPLOSION
    }
    public enum Level
    {
        LEVEL_SMALL,
        LEVEL_MIDDLE,
        LEVEL_BIG,
    }
    public enum Speciality
    {
        POINT_DEFENSE,
        MAIN,
        RUIN,
    }
    public float Damage {
        get { return m_Damage * m_DamageMultiply; }
        set {
            m_Damage = value;
        }
    }
    public float ShutVelocity { 
        get { return m_ShutVelocity * m_ShotVelocityMultiply; } 
        set { m_ShutVelocity = value; } }
    public string ResearchInfluence = InfluenceMG.INFLUENCE_PLAYER;
    public DamageType m_DamageType = DamageType.TYPE_KINETIC;
    public Speciality m_Speciality = Speciality.MAIN;
    public float  m_ShutVelocity = 0.2f;
    public float  BulletFlyVelocity = 5f;
    public float  TurnSpeed =60f;
    public float  m_Damage = 1f;
    public float  m_DamageMultiply = 1f;
    public float m_ShotRangeMultiply = 1f;
    public float m_ShotVelocityMultiply = 1f;
    public float  m_ShotErrorValue = 0;
    public float m_ShotErrorValueBase = 0;
    public float  m_ShotErrorValueMax = 15;
    public float  m_ShotErrorValueIncrement = 0.6f;
    public string WeaponResource = "Perfabs/Weapon/Small/LightMachineGun";
    public string BulletResource = "Perfabs/Bullet/LiveBullet";
    public string m_FireAudioResouce = "Perfabs/Audio/Pa";
    public Level  m_Level = Level.LEVEL_SMALL;
    public bool m_IsCanShot = true;
    public int m_Tag=0;
    public float m_ExplotionScale = 1;

    float ShotErrorValueCooling = 0;//  开火误差冷却
    public virtual float ShutRange {
        set { m_ShutRange = value; }
        get { return m_ShutRange * m_ShotRangeMultiply; }
    }
    public WeaponSlot Slot { get; set; }

    protected float m_ShutRange = 10.0f;
    protected Ship m_Ship;
    public Ship ArmShip;

    public Weapon()
    {
        Description = " 我是武器";
    }

    public virtual void Init(Ship ship, WeaponSlot slot)
    {
        m_Ship = ship;
        Slot = slot;
    }

    public virtual FlyItem FireRequst(GameObject ship, WeaponSlot slot, Vector3 position, Vector3 direction)
    {
        return null;
    }
    public virtual FlyItem Fire(GameObject ship, WeaponSlot slot, Vector3 position, Vector3 direction)
    {
        if(ship)
            m_Ship = ship.GetComponent<Ship>();
        var bullet = BulletPool.get().Take(this);
        var bulletComponent = bullet.GetComponent<FlyItem>();
        ShotErrorValueCooling = 1;
        if (null == bulletComponent)
            return null;
        m_ShotErrorValue = Mathf.Clamp(m_ShotErrorValue + m_ShotErrorValueIncrement, m_ShotErrorValueBase, m_ShotErrorValueMax);
        float errorValueHalf = m_ShotErrorValue / 2;
        float offsetValue = UnityEngine.Random.Range(-errorValueHalf, errorValueHalf);
        bulletComponent.clean();

        bulletComponent.m_Slot = slot;
        bulletComponent.m_ExplotionScale = m_ExplotionScale;
        bulletComponent.InitParameter(position,
            Quaternion.AngleAxis(offsetValue, Vector3.forward) * direction,
            BulletFlyVelocity,
            ShutRange, Damage, m_Type.ToString(), m_DamageType , ship.GetComponent<Ship>(), this);

        if (bulletComponent && m_Ship && UtilsGame.IsServer(m_Ship.gameObject))
            UtilsGame.SpawnInServer(bulletComponent.gameObject);
        PlayFireSound(ship.GetComponent<Ship>(), position);
        return bulletComponent; 
    }

    public virtual void FireOnlyEffect(GameObject ship, WeaponSlot slot, Vector3 position, Vector3 direction)
    {
        PlayFireSound(ship.GetComponent<Ship>(), position);
    }
    public void PlayFireSound(Ship ship, Vector3 position)
    {
        int priority = 100;
        if (ship && InfluenceMG.get().IsPlayer(ship.m_ShipStruct.m_Influence))
            priority = 10;

        SoundsPool.get().PlaySound(m_FireAudioResouce, position, priority);
    }

    public virtual int update()
    {

        ShotErrorValueCooling = Mathf.Max(0, ShotErrorValueCooling - (Time.deltaTime));

        //  误差在没开火的时候不停减小
        m_ShotErrorValue = Mathf.Max(m_ShotErrorValueBase, m_ShotErrorValue - m_ShotErrorValueIncrement * (1 - ShotErrorValueCooling) * Time.deltaTime * 20);
        return 1;
    }

}